#!/usr/bin/python
# -*- coding: utf-8 -*-


# author: hitmoon <zxq_yx_007@163.com>
# date: 2015-12-01
# verion: 1.0

import os.path
import os
import socket
import urllib
import urllib2
import cookielib

import re
import sys
import zipfile
import time
import random
import httplib
import shelve

import smtplib
import random

from email.mime.text import MIMEText

mailto_list=["zxq_yx_007@163.com"]
mail_host="smtp.163.com"
mail_user="zxq_yx_007"
mail_pass="xxxxxx"
socket.setdefaulttimeout(20)

def send_mail(to_list,sub,content):
    me="zxq_yx_007@163.com"
    msg = MIMEText(content,_subtype='plain',_charset='utf-8')
    msg['Subject'] = sub
    msg['From'] = me
    msg['To'] = ";".join(to_list)
    try:
        server = smtplib.SMTP()
        server.connect(mail_host)
        server.login(mail_user,mail_pass)
        server.sendmail(me, to_list, msg.as_string())
        server.close()
        return True
    except Exception, e:
        print str(e)
        return False

#from bs4 import BeautifulSoup as BS
from optparse import OptionParser


agents = ['Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0',
          'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
          'User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
          'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
          'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
          'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
          'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
          'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)',
          'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)',
          'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
          'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
          'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)',
          'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ;  QIHU 360EE)']

agent_len = len(agents) - 1
agent = agents[random.randint(0, agent_len)]

header = [('User-Agent', agent),

('Accept', 'text/html;q=0.9,*/*;q=0.8'),
('Accept-Charset','ISO-8859-1,utf-8;q=0.7,*;q=0.3'),
('Connection','close'),
('Referer', 'http://www.baidu.com')
]


base_sen = "http://www.amazon.cn/gp/search/ref=sr_pg_1?rh=n%3A2016116051%2Cn%3A%212016117051%2Cn%3A760233051%2Cn%3A1397649071%2Cn%3A760240051%2Cp_89%3ASennheiser+%E6%A3%AE%E6%B5%B7%E5%A1%9E%E5%B0%94%2Cp_n_feature_browse-bin%3A2127514051"
base_beyer = "http://www.amazon.cn/s/ref=sr_nr_p_89_1?fst=as%3Aoff&rh=n%3A2016116051%2Cn%3A%212016117051%2Cn%3A760233051%2Cn%3A1397649071%2Cn%3A760240051%2Cp_n_feature_browse-bin%3A2127514051%2Cp_89%3ABeyerdynamic+%E6%8B%9C%E4%BA%9A%E5%8A%A8%E5%8A%9B"
base_akg = "http://www.amazon.cn/s/ref=sr_nr_p_89_1?fst=as%3Aoff&rh=n%3A2016116051%2Cn%3A%212016117051%2Cn%3A760233051%2Cn%3A1397649071%2Cn%3A760240051%2Cp_n_feature_browse-bin%3A2127514051%2Cp_89%3AAKG+%E7%88%B1%E7%A7%91%E6%8A%80"
base_beats = "http://www.amazon.cn/s/ref=sr_nr_p_89_2?srs=760233051&fst=as%3Aoff&rh=n%3A2016116051%2Cn%3A!2016117051%2Cn%3A760233051%2Cn%3A1397649071%2Cn%3A760240051%2Cp_n_feature_browse-bin%3A2127514051%2Cp_89%3ABeats"
base_all = "http://www.amazon.cn/gp/search/ref=sr_nr_p_89_2?srs=760233051&fst=as%3Aoff&rh=n%3A2016116051%2Cn%3A!2016117051%2Cn%3A760233051%2Cn%3A1397649071%2Cn%3A760240051%2Cp_n_feature_browse-bin%3A2127514051"

def get_string_from_file(fname):
    f = open(fname, 'r')
    lines = f.readlines()
    result = ''
    for line in lines:
        result = result + line
    return result


def get_html(url):

    opener = urllib2.build_opener()
    # pretend to be a browser
    opener.addheaders = header

    req = urllib2.Request(url)
    try:
        conn = opener.open(req)
        data = conn.read()
        conn.close()
    except Exception, e:
        print "read url timeout, exit!"
        sys.exit(1)
    data = data.decode('UTF-8')
    return data

def get_html2(url):
    data = get_string_from_file("music.html")
    return data


def info_msg(msg):
    print "\nINFO: " + msg

def warn_msg(msg):
    print "\nWARN: " + msg

def dec_to_hex_unicode(s):

    i = s.find('&#')
    if i >= 0:
        ret = s[:i]
    else:
        return s

    j = s[i:].find(';')
    while i >= 0:
        temp = s[i+2:i+j]
        ret = ret + unichr(int(temp))
        s = s[i+j+1:]
        i = s.find('&#')
        if i >= 0:
            ret = ret + s[:i]
        else:
            ret = ret + s
            break

        j = s[i:].find(';')

    return "".join(ret)

def decode_price(s):
    num = 0
    if s[0] == '￥' or s[0] == '$':
        ret = s[1:]
    elif s[:3] == "EUR":
        ret = s[4:]
    i = ret.rfind('.')
    if i > 0:
        ret = ret[:i].replace(',', '') + ret[i:]
    else:
        if s[:3] == "EUR":
            ret = ret.replace(',', '.')
        else:
            ret = ret.replace(',', '')

    return float(ret)

def main():

    p = OptionParser()

    p.add_option('-b', '--base-url', dest='base_url', default=base_sen, help='default headphone page url')
    p.add_option('-s', '--set-base-url', dest='set_url', default=None, help='set headphone page url from command line')

    re_product_info = re.compile(r'class="a-size-base a-color-null\s*[^"]+">([^<]+)</h2></a></div><div [^>]+>(<span [^>]+>[^<]*</span>){2}</div></div>(<div [^>]+>){2}<a [^>]+ href="[^"]+sr=([^"]+)">\s*<span class="a-size-base a-color-price\s*[^"]+"\s*>([^<]+)</span>')


    options, args = p.parse_args()

    if options.base_url == 'beyer':
        base = base_beyer
    elif options.base_url == 'akg':
        base = base_akg
    elif options.base_url == 'beats':
        base = base_beats
    elif options.base_url == 'all':
        base = base_all
    else:
        base = base_sen

    if options.set_url != None:
        base = options.set_url

    html_page = get_html(base)

    pros = re_product_info.findall(html_page)
    # print len(pros)
    # print pros
    if pros == []:
        print "Match Error!"
        sys.exit(1)

    headphone = []
    last = ""
    i = 0
    while i < len(pros):

        p_name = pros[i][0]
        p_tag = pros[i][3]
        p_price = pros[i][4]

        # print "p_tag = %s" %(p_tag)
        # print "last = %s" %(last)
        index = p_tag.find('&amp')
        if index > 0:
            new_tag = p_tag[:index]
        else:
            new_tag = p_tag
        index = last.find('&amp')
        if index > 0:
            old_tag = last[:index]
        else:
            old_tag = last
        # print "new = %s, old = %s" %(new_tag, old_tag)

        if new_tag != old_tag:
            if "condition=used" not in p_tag:
                headphone += [(dec_to_hex_unicode(p_name), p_price)]

        last = p_tag
        i += 1

    db = shelve.open("my-db")

    prev = ""
    for i in headphone:
        product_name = i[0]
        price_str = i[1]
        price = decode_price(price_str)

        price_prefix = price_str[0]
        if price_prefix == 'E':
            price_prefix = "€ "

        if product_name == prev:
            product_name = prev + "-" + str(ext)
            ext += 1
        else:
            ext = 1
        key = (product_name + price_prefix).encode("utf-8")
        product_name = product_name.encode("utf-8")

        #print "%s: %s"%(i[0], price)
        if db.has_key(key):
            if price < db[key]:
                drop = (db[key] - price) / db[key] * 100
                if drop >= 5 or (db[key] - price) > 50:
                    msg = "Drop(%%%d)! %s%.2f -> %s%.2f :\n%s"%(drop, price_prefix, db[key], price_prefix, price, product_name)
                    if not send_mail(mailto_list, "Drop: %s"%(key[:32]), msg):
                        print "send promotion email error!"
            db[key] = price
        else:
            print "NEW %s: %s%.2f"%(product_name, price_prefix, price)
            db[key] = price
        prev = i[0]

    db.close()

    print "Done!"

if __name__ == "__main__":
    reload(sys)
    sys.setdefaultencoding('utf-8')
    main()

